package com.gragra.parseOptions.tests;
import static org.junit.Assert.*;
import java.io.FileReader;
import java.io.IOException;
import java.io.Writer;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import org.junit.Before;
import org.junit.Test;
import com.gragra.parseOptions.CommandLineException;
import com.gragra.parseOptions.OptionInformation;
import com.gragra.parseOptions.Parser;
public class TestParser
{
	/**
	 * 
	 */
	private Parser parser;
	@Before
	public void setUp() throws Exception
	{
		parser = new Parser();
		parser.setMinArgs(2);
		parser.setMaxArgs(3);
		parser.setArgumentDescription(1, "the input stream that will be used");
		parser.addOption("firstOption", new OptionInformation()
		{
			/**
			 * 
			 */
			private String	empty = "";
			@Override
			public void processArguments(ObjectArrayList<String> arguments)
			{
				StringBuilder sb = new StringBuilder();
				for(String s : arguments)
				{sb.append("|"+s);}
				empty  = sb.toString();
			}
			@Override
			public String toString()
			{return empty;}
			@Override
			public boolean hasBeenSet()
			{return false;}
			@Override
			public String getDescription()
			{
				return "this is definitely an option";
			}
		});
		parser.addName("firstOption", "fO");
		parser.setProgramDescription("This is a Parser instance created to test Parser instances.");
		parser.addOption("alt", new OptionInformation()
		{
			boolean called = false;
			@Override
			public void processArguments(ObjectArrayList<String> arguments)
			{called = true;}
			@Override
			public boolean hasBeenSet()
			{return called;}
			@Override
			public String getDescription()
			{return null;}
		});
		parser.setOptionNecessary("alt");
	}
	@Test
	public void testSetOptionNotnecessary()
	{
		boolean prob = false;
		try
		{
			parser.parse(new String[] {"a","b","c","-firstOption","a","b"});
		}
		catch(CommandLineException e)
		{prob = true;}
		assertTrue(prob);
		parser.setOptionNotnecessary("alt");
		try
		{
			parser.parse(new String[] {"a","b","c","-firstOption","a","b"});
		}
		catch(CommandLineException e)
		{prob = false;}
		assertTrue(prob);
	}
	@Test
	public void testGetFileWriterFromArgument() throws CommandLineException, IOException
	{
		parser.parse(new String[] {"a","b","c","-firstOption","a","b","-alt"});
		Writer fw = parser.getFileWriterFromArgument(1);
		assertFalse(fw == null);
		fw.close();
	}
	@Test
	public void testGetFileReaderFromArgument() throws CommandLineException, IOException
	{
		parser.parse(new String[] {"a","b","c","-firstOption","a","b","-alt"});
		FileReader fw = parser.getFileReaderFromArgument(1);
		assertFalse(fw == null);
		fw.close();
	}
	@Test
	public void testGetArgument() throws CommandLineException
	{
		parser.parse(new String[] {"a","b","c","-firstOption","a","b","-alt"});
		assertEquals("a",parser.getArgument(0));
		assertEquals("b",parser.getArgument(1));
		assertEquals("c",parser.getArgument(2));
	}
	@Test
	public void testGetProgramDescription()
	{assertEquals("This is a Parser instance created to test Parser instances.",parser.getProgramDescription());}
	@Test
	public void testIgnoreUnknown()
	{
		assertTrue(parser.ignoreUnknown());
		parser.setIgnoreUnknown(false);
		boolean except = false;
		try
		{
			parser.parse(new String[] {"a","b","c","-firstOption","a","b","-alt","-mom"});
		}
		catch(CommandLineException e)
		{except = true;}
		assertTrue(except);
		assertFalse(parser.ignoreUnknown());
	}
	@Test
	public void testParse() throws CommandLineException
	{
		parser.parse(new String[] {"a","b","c","-fO","ma","pa","-alt"});
		OptionInformation oi = parser.getInformation("alt");
		assertTrue(oi.hasBeenSet());
		assertEquals("|ma|pa",parser.getInformation("firstOption").toString());
		parser.parse(new String[] {"a","b","c","-fO","da","da","-alt"});
		assertEquals("|da|da",parser.getInformation("fO").toString());
		parser.parse(new String[] {"a","b","c","-firstOption","ha","ha","-alt"});
		assertEquals("|ha|ha",parser.getInformation("fO").toString());
		parser.parse(new String[] {"a","b","c","-firstOption","gra","gra","-alt"});
		assertEquals("|gra|gra",parser.getInformation("firstOption").toString());
		assertFalse(parser.hadHelp());
		parser.parse(new String[] {"a","b","c","-firstOption","gra","-h","gra","-alt"});
		assertTrue(parser.hadHelp());
		parser.parse(new String[] {"a","b","c","-firstOption","gra","gra","-alt"});
		assertFalse(parser.hadHelp());
		parser.parse(new String[] {"a","b","c","-firstOption","gra","-help","gra","-alt"});
		assertTrue(parser.hadHelp());
		parser.parse(new String[] {"a","b","c","-firstOption","gra","gra","-alt"});
		assertFalse(parser.hadHelp());
		boolean caught = false;
		try
		{parser.parse(new String[] {"a","-firstOption","gra","gra","-alt"});}
		catch(CommandLineException e)
		{caught  = true;}
		assertTrue(caught);
		caught = false;
		try
		{parser.parse(new String[] {"a","b","b","b","-firstOption","gra","gra","-alt"});}
		catch(CommandLineException e)
		{caught  = true;}
		assertTrue(caught);
	}
	@Test
	public void testWriteOutHelp()
	{
		String[] parts = parser.writeOutHelp().split("\n");
		assertEquals("This is a Parser instance created to test Parser instances.",parts[0]);
		assertEquals(12,parts.length);
		assertEquals("Usage is: argument_1 argument_2 ... -option_1 value_1 value_2 ... -option_2 value_1 value_2 ... ",parts[1]);
		assertEquals("The minimum Number of arguments is: 2",parts[2]);
		assertEquals("The maximum Number of arguments is: 3",parts[3]);
		assertEquals("Argument descriptions are:",parts[4]);
		assertEquals("Argument number: 0 - no Description given for this Argument",parts[5]);
		assertEquals("Argument number: 1 - the input stream that will be used",parts[6]);
		assertEquals("The options and their descriptions are:",parts[7]);
		assertEquals("-h -help print this message",parts[8]);
		assertEquals("-alt null",parts[9]);
		assertEquals("This option is necessary.",parts[10]);
		assertEquals("-firstOption -fO this is definitely an option",parts[11]);
	}
}